This notebook documents the process for running the SOT/OTS monthly scripts in R. Preceding these scripts is a SQL procedure and the end output is a collection of .csv files. The following document will demonstrate the process for creating the Master tables and also the output of a single .csv file.
First we need to load our libraries.
The following code will open a system-independent, file chooser using Java and the function created above. It will allow you to choose the directory in which to save all files. This will sometimes fail the first time it is run. If it fails just rerun it (usually works the second time). Note: Eval is set to off to disable dynamic functionality for this notebook. This notebook will use the current working directory instead.
Next we need to create a connection to EDWP. Once you have stored your username and password as my_uid and my_pwd; and created a DSN, connect with a string similar to this (You may need to change the below if you gave your DSN an different name). Then verify that we have successfully connected by performing a query on the dbcinfo table.
Then we create our master tables via query and store them as R objects.
For the purpose of this notebook, however, we will not query the database. Instead, we will load objects already created and stored on the corporate FTP server.
Now let’s download a few static files from Github and save the master objects we just created. We will need these for static mapping.
And create a few tables by joining and summarising.
Lastly we need to output this file as a csv. The file will be output to the directory you set up using the Java file chooser earlier (deactivated for this notebook).
That is it! The basic process is complete. The remaining tables can be created in much the same way.
Appendix
# Create Monthly SOT Brand Table ----
Monthly_Brand_SOT <- SOT_Master %>%
filter(SOT_Master$ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth, ReportingBrand) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
ReportingBrand,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Brand_SOT)
# Create Monthly SOT Category Table ----
Monthly_Category_SOT <- SOT_Master %>%
filter(SOT_Master$ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth, Category) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
Category,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Category_SOT)
# Create Monthly Gap Inc SOT Table ----
Monthly_GapInc_SOT <- SOT_Master %>%
filter(SOT_Master$ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_GapInc_SOT)
# Create Monthly OTS Brand and Category Table ----
Monthly_Brand_Category_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number, ReportingBrand, Category) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
ReportingBrand,
Category,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_Brand_Category_OTS)
# Create Monthly OTS Brand Table ----
Monthly_Brand_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number, ReportingBrand) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
ReportingBrand,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_Brand_OTS)
# Create Monthly OTS Category Table ----
Monthly_Category_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number, Category) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
Category,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_Category_OTS)
# Create Monthly Gap Inc OTS Table ----
Monthly_GapInc_OTS <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Month_Number) %>%
summarise("OTSUnits" = sum(Units),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_GapInc_OTS)
# Create Monthly - Preferred Vendor - New ----
Monthly_Preferred_Vendor_new <- inner_join(SOT_Master, Preferred_Vendor_new, by = c("Category"= "New Category", "Parent_Vendor"="Vendor Name")) %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(Category, Parent_Vendor, ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(Category,
Parent_Vendor,
ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits) %>%
arrange(ShipCancelMonth, Category)
# Create Monthly Preferred Vendor - New OTS ----
Monthly_Preferred_Vendor_New_OTS <- inner_join(OTS_Master, Preferred_Vendor_new, by = c("Category"= "New Category", "Parent_Vendor"="Vendor Name")) %>%
filter(Week <= EOW) %>%
group_by(Category, Parent_Vendor, Month_Number ) %>%
summarise("OTSUnits" = floor(sum(Units)),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Category,
Parent_Vendor,
Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits) %>%
arrange(Month_Number, Category)
# View(Monthly_Preferred_Vendor_New_OTS)
# Create Monthly Brand and Category Combine Table ----
Monthly_Brand_Category_Combine <- left_join(Monthly_Brand_Category_SOT, Monthly_Brand_Category_OTS, by= c("ShipCancelMonth"="Month_Number", "ReportingBrand"="ReportingBrand", "Category"="Category"))
Monthly_Brand_Category_Combine <- Monthly_Brand_Category_Combine[c(1:8, 13:17,9:10,18,11:12)]
# Create Monthly SOT Brand Combine Table ----
Monthly_Brand_Combine <- left_join(Monthly_Brand_SOT, Monthly_Brand_OTS, by= c("ShipCancelMonth"="Month_Number", "ReportingBrand"="ReportingBrand"))
Monthly_Brand_Combine <- Monthly_Brand_Combine[c(1:7, 12:16, 8:9, 17, 10:11)]
# View(Monthly_Brand_Combine)
# Create Monthly SOT Category Combine Table ----
Monthly_Category_Combine <- left_join(Monthly_Category_SOT, Monthly_Category_OTS, by= c("ShipCancelMonth"="Month_Number", "Category"="Category"))
Monthly_Category_Combine <- Monthly_Category_Combine[c(1:7, 12:16, 8:9, 17, 10:11)]
# View(Monthly_Category_Combine)
# Create Monthly SOT Gap Inc Combine Table ----
Monthly_GapInc_Combine <- left_join(Monthly_GapInc_SOT, Monthly_GapInc_OTS, by= c("ShipCancelMonth"="Month_Number"))
Monthly_GapInc_Combine <- Monthly_GapInc_Combine[c(1:6, 11:15,7:8,16,9:10)]
# View(Monthly_GapInc_Combine)
# Create Preferred Vendor Combine Table ----
Preferred_Vendor_New_Combine <- left_join(Monthly_Preferred_Vendor_new, Monthly_Preferred_Vendor_New_OTS, by = c("Category"="Category", "Parent_Vendor"="Parent_Vendor", "ShipCancelMonth" = "Month_Number"))
Preferred_Vendor_New_Combine <-Preferred_Vendor_New_Combine[c(1:8, 13:17, 9:10, 18, 11:12)]
# Create Monthly - byDC
Monthly_by_DC <- OTS_Master %>%
filter(OTS_Master$Week <= EOW) %>%
group_by(Fiscal_Month, Month_Number, DCCampus, DC_NAME, DestCtryCD) %>%
summarise("Total Units" = floor(sum(Units)),
"OnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTS%" = sum(Units[Lateness=="OnTime"])/sum(Units),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"LateUnits"= floor(sum(Units[Lateness=="Late"]))) %>%
select(Fiscal_Month,
Month_Number,
`OnTimeUnits`,
`Total Units`,
DCCampus,
DC_NAME,
DestCtryCD,
`OTS%`,
`OTSLate5daysUnits`,
`WTOTSLateUnits`,
`LateUnits`)
# Create Top 20 Countries SOT ----
Monthly_Top_20_SOT <- inner_join(SOT_Master, Top_20_Countries, by = c("CountryOfOrigin"= "CountryOfOrigin"))
Monthly_Top_20_SOT <- Monthly_Top_20_SOT %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Top_20_SOT)
# Create Monthly Top 20 OTS Table ----
Monthly_TOP_20_OTS <- inner_join(OTS_Master, Top_20_Countries, by = c("ORIGIN_COUNTRY_CODE"="CountryOfOrigin"))
Monthly_TOP_20_OTS <- Monthly_TOP_20_OTS %>%
filter(Week <= EOW) %>%
group_by(Month_Number) %>%
summarise("OTSUnits" = sum(Units),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_TOP_20_OTS)
# Create Monthly Top 20 Combine table ----
Monthly_Top_20_Combine <- inner_join(Monthly_Top_20_SOT, Monthly_TOP_20_OTS, by= c("ShipCancelMonth"="Month_Number"))
Monthly_Top_20_Combine <- Monthly_Top_20_Combine[c(1:6, 11:15,7:8,16,9:10)]
# Create Monthly Top 50 Vendors SOT Table ----
Monthly_Top_50_Vendors_SOT <- inner_join(SOT_Master, Top_50_Vendors, by = c("Parent_Vendor"= "Parent_Vendor"))
Monthly_Top_50_Vendors_SOT <- Monthly_Top_50_Vendors_SOT %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(ShipCancelMonth) %>%
summarise("SOTUnits" = floor(sum(Units)),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(ShipCancelMonth,
SOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits,
PPAUnits,
PPASOTLateUnits,
PPASOT5daysLateUnits,
WTPPASOTLateUnits)
# View(Monthly_Top_50_Vendors_SOT)
# Create Monthly Top 50 Vendors OTS Table ----
Monthly_Top_50_Vendors_OTS <- inner_join(OTS_Master, Top_50_Vendors, by = c("Parent_Vendor"= "Parent_Vendor"))
Monthly_Top_50_Vendors_OTS <- Monthly_Top_50_Vendors_OTS %>%
filter(Week <= EOW) %>%
group_by(Month_Number) %>%
summarise("OTSUnits" = sum(Units),
"OTSOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"OTSLateUnits"= floor(sum(Units[Lateness=="Late"])),
"OTSLate5daysUnits" = floor(sum(Units[Lateness=="Late" & Days_Late > 5])),
"WTOTSLateUnits" = floor(sum(Units[Lateness=="Late"]*Days_Late[Lateness=="Late" & Days_Late >=1])),
"PPAOTSLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]))) %>%
select(Month_Number,
OTSUnits,
OTSOnTimeUnits,
OTSLateUnits,
OTSLate5daysUnits,
WTOTSLateUnits,
PPAOTSLateUnits)
# View(Monthly_GapInc_OTS)
# Create Monthly SOT Top 50 Vendors Combine Table ----
Monthly_Top_50_Vendors_Combine <- left_join(Monthly_Top_50_Vendors_SOT, Monthly_Top_50_Vendors_OTS, by= c("ShipCancelMonth"="Month_Number"))
Monthly_Top_50_Vendors_Combine <- Monthly_Top_50_Vendors_Combine[c(1:6, 11:15,7:8,16,9:10)]
# View(Monthly_Top_50__Vendors_Combine)
# Create OTSvsSOT table ----
OTS_vs <- OTS_Master %>%
select(NUMBER_SEQ, Month_Number, Lateness, Units) %>%
filter(Lateness!= "Undetermined") %>%
rename("StockedOnTime" = Lateness) %>%
group_by(Month_Number, StockedOnTime) %>%
droplevels()
SOT_vs <- SOT_Master %>%
select(NUMBER_SEQ, ShipCancelMonth, Lateness) %>%
filter(Lateness!="Unmeasured") %>%
rename("ShippedOnTime" = Lateness) %>%
group_by(ShipCancelMonth, ShippedOnTime) %>%
droplevels()
OTSvsSOT <- inner_join(OTS_vs, SOT_vs, by = c("NUMBER_SEQ"= "NUMBER_SEQ")) %>%
group_by(Month_Number, StockedOnTime, ShippedOnTime) %>%
summarise("SumOfUnits" = floor(sum(Units)))
# Create Monthly Brand Top 10 Delay Combine ----
Brand_Top_Ten_Delay <- SOT_Master %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(ReportingBrand, ShipCancelMonth, Parent_Vendor) %>%
summarise("SOTUnits" = floor(sum(Units)),
"AdjustedSOTUnits"= floor(sum(Units[Lateness=="OnTime"]) + sum(Units[Lateness=="Late"])),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(
ReportingBrand,
ShipCancelMonth,
Parent_Vendor,
SOTUnits,
AdjustedSOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits) %>%
top_n(10, SOTLateUnits) %>%
arrange(ReportingBrand,ShipCancelMonth, desc(SOTLateUnits))
# Create Monthly Category Top 10 Delay Combine ----
Category_Top_Ten_Delay <- SOT_Master %>%
filter(ShipCancelWeek <= EOW) %>%
group_by(Category, ShipCancelMonth, Parent_Vendor) %>%
summarise("SOTUnits" = floor(sum(Units)),
"AdjustedSOTUnits"= floor(sum(Units[Lateness=="OnTime"]) + sum(Units[Lateness=="Late"])),
"SOTOnTimeUnits" = floor(sum(Units[Lateness=="OnTime"])),
"SOTLateUnits"= floor(sum(Units[Lateness=="Late"])),
"SOTLate5daysUnits" = floor(sum(Units[Lateness=="Late" & DAYS_LATE > 5])),
"WTSOTLateUnits" = floor(sum(Units[Lateness=="Late"]*DAYS_LATE[Lateness=="Late" & DAYS_LATE >=1])),
"PPAUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir"])),
"PPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"])),
"PPASOT5daysLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE>5])),
"WTPPASOTLateUnits" = floor(sum(Units[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late"]*DAYS_LATE[SHP_MODE_CATG_NM == "PrepaidAir" & Lateness=="Late" & DAYS_LATE >=1]))) %>%
select(
Category,
ShipCancelMonth,
Parent_Vendor,
SOTUnits,
AdjustedSOTUnits,
SOTOnTimeUnits,
SOTLateUnits,
SOTLate5daysUnits,
WTSOTLateUnits) %>%
top_n(10, SOTLateUnits) %>%
arrange(Category, ShipCancelMonth, desc(SOTLateUnits))
# Write tables ----
write_csv(Monthly_Brand_Category_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Brand_Category_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Brand_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Brand_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Category_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Category_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_GapInc_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_GapInc_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Preferred_Vendor_New_Combine,
path = paste(SOT_OTS_directory,
paste('Preferred_Vendor_New_Combine_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_by_DC,
path = paste(SOT_OTS_directory,
paste('Monthly_by_DC_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Top_20_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Top_20_Countries_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Monthly_Top_50_Vendors_Combine,
path = paste(SOT_OTS_directory,
paste('Monthly_Top_50_Vendors_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(OTSvsSOT,
path = paste(SOT_OTS_directory,
paste('OTSvsSOT_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Brand_Top_Ten_Delay,
path = paste(SOT_OTS_directory,
paste('Brand_Top_10_Delay_WE_', EOW, '.csv',sep = ""), sep = '/' ))
write_csv(Category_Top_Ten_Delay,
path = paste(SOT_OTS_directory,
paste('Category_Top_10_Delay_WE_', EOW, '.csv',sep = ""), sep = '/' ))
LS0tDQp0aXRsZTogIlNPVC9PVFMgTW9udGhseSBOb3RlYm9vayINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KLS0tDQpUaGlzIG5vdGVib29rIGRvY3VtZW50cyB0aGUgcHJvY2VzcyBmb3IgcnVubmluZyB0aGUgU09UL09UUyBtb250aGx5IHNjcmlwdHMgaW4gUi4gUHJlY2VkaW5nIHRoZXNlIHNjcmlwdHMgaXMgYSBTUUwgcHJvY2VkdXJlIGFuZCB0aGUgZW5kIG91dHB1dCBpcyBhIGNvbGxlY3Rpb24gb2YgLmNzdiBmaWxlcy4gVGhlIGZvbGxvd2luZyBkb2N1bWVudCB3aWxsIGRlbW9uc3RyYXRlIHRoZSBwcm9jZXNzIGZvciBjcmVhdGluZyB0aGUgTWFzdGVyIHRhYmxlcyBhbmQgYWxzbyB0aGUgb3V0cHV0IG9mIGEgc2luZ2xlIC5jc3YgZmlsZS4gDQoNCkZpcnN0IHdlIG5lZWQgdG8gbG9hZCBvdXIgbGlicmFyaWVzLg0KYGBge3Igd2FybmluZz1GQUxTRSwgZXJyb3I9RkFMU0UsIGNvbW1lbnQ9IEZBTFNFfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KFJPREJDKQ0KbGlicmFyeShmb3JtYXR0YWJsZSkNCmxpYnJhcnkoUkpEQkMpDQpsaWJyYXJ5KHJDaG9pY2VEaWFsb2dzKQ0KbGlicmFyeShSQ3VybCkNCg0KYGBgDQoNClRoZW4gc2V0IHVwIG91ciBFbnZpcm9ubWVudCB3aXRoIGEgZmV3IGZ1bmN0aW9uczoNCmBgYHtyIGV2YWw9RkFMU0V9DQojIHNldHVwIGVudmlyb25tZW50IC0tLS0NCnByb21wdF9mb3Jfd2VlayA8LSBmdW5jdGlvbigpDQp7IA0KICBuIDwtIHJlYWRsaW5lKHByb21wdD0iRW50ZXIgV2VlayBudW1iZXI6ICIpDQogIHJldHVybihhcy5pbnRlZ2VyKG4pKQ0KfQ0KY2hvb3NlX2ZpbGVfZGlyZWN0b3J5IDwtIGZ1bmN0aW9uKCkNCnsNCiAgdiA8LSBqY2hvb3NlLmRpcigpDQogIHJldHVybih2KQ0KfQ0KDQpgYGANCg0KVGhlIGZvbGxvd2luZyBjb2RlIHdpbGwgb3BlbiBhIHN5c3RlbS1pbmRlcGVuZGVudCwgZmlsZSBjaG9vc2VyIHVzaW5nIEphdmEgYW5kIHRoZSBmdW5jdGlvbiBjcmVhdGVkIGFib3ZlLiBJdCB3aWxsIGFsbG93IHlvdSB0byBjaG9vc2UgdGhlIGRpcmVjdG9yeSBpbiB3aGljaCB0byBzYXZlIGFsbCBmaWxlcy4gVGhpcyB3aWxsIHNvbWV0aW1lcyBmYWlsIHRoZSBmaXJzdCB0aW1lIGl0IGlzIHJ1bi4gSWYgaXQgZmFpbHMganVzdCByZXJ1biBpdCAodXN1YWxseSB3b3JrcyB0aGUgc2Vjb25kIHRpbWUpLiBOb3RlOiBFdmFsIGlzIHNldCB0byBvZmYgdG8gZGlzYWJsZSBkeW5hbWljIGZ1bmN0aW9uYWxpdHkgZm9yIHRoaXMgbm90ZWJvb2suIFRoaXMgbm90ZWJvb2sgd2lsbCB1c2UgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgaW5zdGVhZC4gIA0KYGBge3IgZXZhbD1GQUxTRX0NClNPVF9PVFNfZGlyZWN0b3J5IDwtIGNob29zZV9maWxlX2RpcmVjdG9yeSgpDQpgYGANCg0KDQpgYGB7ciBldmFsPUZBTFNFfQ0KRU9XIDwtIHByb21wdF9mb3Jfd2VlaygpDQpgYGANCmBgYHtyIGluY2x1ZGU9RkFMU0V9DQpFT1cgPC0gNDgNCg0KYGBgDQoNCk5leHQgd2UgbmVlZCB0byBjcmVhdGUgYSBjb25uZWN0aW9uIHRvIEVEV1AuIE9uY2UgeW91IGhhdmUgc3RvcmVkIHlvdXIgdXNlcm5hbWUgYW5kIHBhc3N3b3JkIGFzIG15X3VpZCBhbmQgbXlfcHdkOyBhbmQgY3JlYXRlZCBhIERTTiwgY29ubmVjdCB3aXRoIGEgc3RyaW5nIHNpbWlsYXIgdG8gdGhpcyAoWW91IG1heSBuZWVkIHRvIGNoYW5nZSB0aGUgYmVsb3cgaWYgeW91IGdhdmUgeW91ciBEU04gYW4gZGlmZmVyZW50ICBuYW1lKS4gVGhlbiB2ZXJpZnkgdGhhdCB3ZSBoYXZlIHN1Y2Nlc3NmdWxseSBjb25uZWN0ZWQgYnkgcGVyZm9ybWluZyBhIHF1ZXJ5IG9uIHRoZSBkYmNpbmZvIHRhYmxlLg0KDQpgYGB7ciB3YXJuaW5nID0gRkFMU0V9DQojIENyZWF0ZSBST0RCQyBjb25uZWN0aW9uLS0tLSANCm15X2Nvbm5lY3QgPC0gb2RiY0Nvbm5lY3QoZHNuPSAiSVAgRURXUCIsIHVpZD0gbXlfdWlkLCBwd2Q9IG15X3B3ZCkNCnNxbFF1ZXJ5KG15X2Nvbm5lY3QsIHF1ZXJ5ID0gIlNFTEVDVCAgKiBmcm9tIGRiYy5kYmNpbmZvOyIpDQpgYGANCldlIGNhbiBzZWUgdGhhdCB0aGUgc2VydmVyIGhhcyByZXR1cm5lZCBvdXIgdGFibGUhIFdlIGhhdmUgY29ubmVjdGVkISANCg0KVGhlbiB3ZSBjcmVhdGUgb3VyIG1hc3RlciB0YWJsZXMgdmlhIHF1ZXJ5IGFuZCBzdG9yZSB0aGVtIGFzIFIgb2JqZWN0cy4NCmBgYHtyIGV2YWw9RkFMU0V9DQojIFF1ZXJ5IEVEVyAtLS0tDQpTT1RfTWFzdGVyIDwtIHNxbFF1ZXJ5KG15X2Nvbm5lY3QsIA0KICAgICAgICAgICAgICAgICAgICAgICBxdWVyeSA9ICJTRUxFQ1QgICogZnJvbSBTUkFBX1NBTkQuVklFV19TT1RfTUFTVEVSOyIpDQoNCk9UU19NYXN0ZXIgPC0gc3FsUXVlcnkobXlfY29ubmVjdCwgDQogICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5ID0gIlNFTEVDVCAgKiBmcm9tIFNSQUFfU0FORC5WSUVXX09UU19NQVNURVI7IikNCmNsb3NlKG15X2Nvbm5lY3QpDQpgYGANCg0KRm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgbm90ZWJvb2ssIGhvd2V2ZXIsIHdlIHdpbGwgbm90IHF1ZXJ5IHRoZSBkYXRhYmFzZS4gSW5zdGVhZCwgd2Ugd2lsbCBsb2FkIG9iamVjdHMgYWxyZWFkeSBjcmVhdGVkIGFuZCBzdG9yZWQgb24gdGhlIGNvcnBvcmF0ZSBGVFAgc2VydmVyLiAgDQpgYGB7ciBlY2hvPUZBTFNFfQ0KU09UX2Nvbm4gPC0gdXJsKCJmdHA6Ly9mdHAuZ2FwLmNvbS9kYXRhL3RvX2hxL1N1cHBseUNoYWluUmVwb3J0aW5nL0dTQ0FUL1NPVE1hc3Rlck9iamVjdHMvU09UX01hc3Rlcl9vYmplY3QucnRmIikNCk9UU19jb25uIDwtIHVybCgiZnRwOi8vZnRwLmdhcC5jb20vZGF0YS90b19ocS9TdXBwbHlDaGFpblJlcG9ydGluZy9HU0NBVC9TT1RNYXN0ZXJPYmplY3RzL09UU19NYXN0ZXJfb2JqZWN0LnJ0ZiIpDQogDQpsb2FkKFNPVF9jb25uKQ0KbG9hZChPVFNfY29ubikNCmBgYA0KDQpOb3cgbGV0J3MgZG93bmxvYWQgYSBmZXcgc3RhdGljIGZpbGVzIGZyb20gR2l0aHViIGFuZCBzYXZlIHRoZSBtYXN0ZXIgb2JqZWN0cyB3ZSBqdXN0IGNyZWF0ZWQuIFdlIHdpbGwgbmVlZCB0aGVzZSBmb3Igc3RhdGljIG1hcHBpbmcuIA0KYGBge3J9DQojIEltcG9ydCBzdGF0aWMgZmlsZXMgLS0tLQ0KcHJlZl9jb25uIDwtIGdldFVSTCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0dTQ0FUL01vbnRobHlfU09UL21hc3Rlci9QcmVmZXJyZWQlMjBWZW5kb3IlMjAobmV3KS5jc3YiKQ0KUHJlZmVycmVkX1ZlbmRvcl9uZXcgPC0gcmVhZF9kZWxpbShmaWxlID0gcHJlZl9jb25uLCBkZWxpbSA9ICJeIikNCnByZWZfY29ubiA8LSBnZXRVUkwoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9HU0NBVC9Nb250aGx5X1NPVC9tYXN0ZXIvQ291bnRyeSUyMERlc2NyaXB0aW9uLnR4dCIpDQpDb3VudHJ5X2Rlc2NyaXB0aW9uIDwtIHJlYWRfZGVsaW0oZmlsZSA9IHByZWZfY29ubiwgZGVsaW0gPSAiXiIpDQpgYGANCmBgYHtyIGV2YWw9RkFMU0V9DQojIHNhdmUgTWFzdGVyIE9iamVjdHMgLS0tLQ0Kc2F2ZShTT1RfTWFzdGVyLCBmaWxlID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICAnU09UX01hc3Rlcl9vYmplY3QucnRmJywgc2VwID0gLlBsYXRmb3JtJGZpbGUuc2VwKSkNCnNhdmUoT1RTX01hc3RlciwgZmlsZSA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgJ09UU19NYXN0ZXJfb2JqZWN0LnJ0ZicsIHNlcCA9IC5QbGF0Zm9ybSRmaWxlLnNlcCApKQ0KYGBgDQoNCkFuZCBjcmVhdGUgYSBmZXcgdGFibGVzIGJ5IGpvaW5pbmcgYW5kIHN1bW1hcmlzaW5nLg0KDQpgYGB7cn0NCiMgQ3JlYXRlIFRPUCAyMCBDb3VudHJpZXMgVGFibGUgLS0tLQ0KVG9wXzIwX0NvdW50cmllcyA8LSBsZWZ0X2pvaW4oU09UX01hc3RlciwgQ291bnRyeV9kZXNjcmlwdGlvbiwgYnk9IGMoIkNvdW50cnlPZk9yaWdpbiI9IkNUUllfQ0QiICkpDQpUb3BfMjBfQ291bnRyaWVzIDwtIFRvcF8yMF9Db3VudHJpZXMgJT4lIA0KICBncm91cF9ieShDb3VudHJ5T2ZPcmlnaW4sIENUUllfREVTQykgJT4lIA0KICBzdW1tYXJpc2UoIlVuaXRzIGJ5IENvdW50cnkiID0gZmxvb3Ioc3VtKFVuaXRzKSkpICU+JSANCiAgYXJyYW5nZShkZXNjKGBVbml0cyBieSBDb3VudHJ5YCkpICU+JSANCiAgaGVhZCgyMCkgDQojIENyZWF0ZSB0b3AgNTAgVmVuZG9ycyAtLS0tDQpUb3BfNTBfVmVuZG9ycyA8LSBTT1RfTWFzdGVyICU+JSANCiAgZ3JvdXBfYnkoUGFyZW50X1ZlbmRvcikgJT4lIA0KICBzdW1tYXJpc2UoIlVuaXRzIGJ5IFZlbmRvciIgPSBmbG9vcihzdW0oVW5pdHMpKSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoYFVuaXRzIGJ5IFZlbmRvcmApKSAlPiUgDQogIGhlYWQoNTApDQpgYGANCg0KQ2hlY2sgdGhlIGZpcnN0IDYgcm93cyBvZiBTT1QgTWFzdGVyIHRvIHRlc3QgdGhhdCBvdXIgbG9hZCgpIHdhcyBzdWNjZXNzZnVsOg0KYGBge3J9DQpoZWFkKFNPVF9NYXN0ZXIpDQpgYGANCg0KT25jZSB3ZSBoYXZlIG91ciBtYXN0ZXIgdGFibGVzIGFzIFIgb2JqZWN0cyB3ZSBuZWVkIHRvIGNsZWFuIHRoZW0gdXAgYSBiaXQ6DQpgYGB7cn0NCiMgUmVtb3ZlIG5vaXNlIGZyb20gT1RTIGFuZCBTT1QgTWFzdGVyDQpPVFNfTWFzdGVyIDwtIE9UU19NYXN0ZXIgJT4lIA0KICBmaWx0ZXIoV2VlayA8PSBFT1csDQogICAgICAgICAhZ3JlcGwoIkxpYmVydHkgRGlzdHJpYnV0aW9uIiwgUGFyZW50X1ZlbmRvciwgaWdub3JlLmNhc2UgPSBUUlVFKSwNCiAgICAgICAgICFncmVwbCgiZHVtbXkiLCBQYXJlbnRfVmVuZG9yLCBpZ25vcmUuY2FzZSA9IFRSVUUpLA0KICAgICAgICAgIWdyZXBsKCJKUEYiLCBEQ19OQU1FLCBpZ25vcmUuY2FzZSA9IFRSVUUpKSANCg0KU09UX01hc3RlciA8LSBTT1RfTWFzdGVyICU+JSANCiAgZmlsdGVyKFNoaXBDYW5jZWxXZWVrIDw9IEVPVywNCiAgICAgICAgICFncmVwbCgiTGliZXJ0eSBEaXN0cmlidXRpb24iLCBQYXJlbnRfVmVuZG9yLCBpZ25vcmUuY2FzZSA9IFRSVUUpLA0KICAgICAgICAgIWdyZXBsKCJkdW1teSIsIFBhcmVudF9WZW5kb3IsIGlnbm9yZS5jYXNlID0gVFJVRSksDQogICAgICAgICBNZXRyaWNTaGlwRGF0ZSA8PSBTeXMuRGF0ZSgpKSANCmBgYA0KDQoNCkluIHRoZSBhY3R1YWwgc2NyaXB0IF9NYXN0ZXJfSW1wb3J0LlJfIHRoZXJlIGFyZSBtYW55IHRhYmxlcyB0aGF0IGFyZSBnZW5lcmF0ZWQgZnJvbSB0aGUgYWJvdmUgTWFzdGVyIHRhYmxlcy4gVGhlIGZvbGxvd2luZyBjb2RlIGlzIGFuIGV4YW1wbGUgb2Ygb25lIG91dHB1dCB0aGF0IHdpbGwgaWxsdXN0cmF0ZSB0aGUgcHJvY2VzcyBmb3IgYWxsLiBUaGUgcmVtYWluaW5nIGNvZGUgd2lsbCBiZSByZXNlcnZlZCBmb3IgdGhlIGFwcGVuZGl4IG9mIHRoaXMgZG9jdW1lbnQuDQoNCmBgYHtyfQ0KTW9udGhseV9CcmFuZF9DYXRlZ29yeV9TT1QgPC0gU09UX01hc3RlciAlPiUNCiAgZmlsdGVyKFNPVF9NYXN0ZXIkU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoU2hpcENhbmNlbE1vbnRoLCBSZXBvcnRpbmdCcmFuZCwgQ2F0ZWdvcnkpICU+JSANCiAgc3VtbWFyaXNlKCJTT1RVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJTT1RPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAiV1RTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSwNCiAgICAgICAgICAgICJQUEFVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciJdKSksDQogICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgIlBQQVNPVDVkYXlzTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEU+NV0pKSwNCiAgICAgICAgICAgICJXVFBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSkgJT4lICANCiAgc2VsZWN0KFNoaXBDYW5jZWxNb250aCwgDQogICAgICAgICBSZXBvcnRpbmdCcmFuZCwgDQogICAgICAgICBDYXRlZ29yeSwgDQogICAgICAgICBTT1RVbml0cywgDQogICAgICAgICBTT1RPblRpbWVVbml0cywgDQogICAgICAgICBTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBVW5pdHMsDQogICAgICAgICBQUEFTT1RMYXRlVW5pdHMsDQogICAgICAgICBQUEFTT1Q1ZGF5c0xhdGVVbml0cywNCiAgICAgICAgIFdUUFBBU09UTGF0ZVVuaXRzKQ0KYGBgDQoNClRha2luZyBhIGxvb2sgYXQgb3VyIG5ldyB0YWJsZToNCg0KYGBge3IgZWNobz1GQUxTRX0NCmZvcm1hdChNb250aGx5X0JyYW5kX0NhdGVnb3J5X1NPVFtzYW1wbGUoMTpucm93KE1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfU09UKSwgMTApLCBdLCBiaWcubWFyayA9ICIsIikNCmBgYA0KDQpMYXN0bHkgd2UgbmVlZCB0byBvdXRwdXQgdGhpcyBmaWxlIGFzIGEgY3N2LiBUaGUgZmlsZSB3aWxsIGJlIG91dHB1dCB0byB0aGUgZGlyZWN0b3J5IHlvdSBzZXQgdXAgdXNpbmcgdGhlIEphdmEgZmlsZSBjaG9vc2VyIGVhcmxpZXIgKGRlYWN0aXZhdGVkIGZvciB0aGlzIG5vdGVib29rKS4gIA0KYGBge3IgZXZhbD1GQUxTRX0NCndyaXRlX2NzdihNb250aGx5X0JyYW5kX0NhdGVnb3J5X0NvbWJpbmUsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnTW9udGhseV9CcmFuZF9DYXRlZ29yeV9Db21iaW5lX1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQpgYGANCg0KVGhhdCBpcyBpdCEgVGhlIGJhc2ljIHByb2Nlc3MgaXMgY29tcGxldGUuIFRoZSByZW1haW5pbmcgdGFibGVzIGNhbiBiZSBjcmVhdGVkIGluIG11Y2ggdGhlIHNhbWUgd2F5Lg0KDQpccGFnZWJyZWFrDQoNCiMjIEFwcGVuZGl4DQoNCmBgYHtyIGV2YWw9RkFMU0V9DQojIENyZWF0ZSBNb250aGx5IFNPVCBCcmFuZCBUYWJsZSAtLS0tDQpNb250aGx5X0JyYW5kX1NPVCA8LSBTT1RfTWFzdGVyICU+JQ0KICBmaWx0ZXIoU09UX01hc3RlciRTaGlwQ2FuY2VsV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShTaGlwQ2FuY2VsTW9udGgsIFJlcG9ydGluZ0JyYW5kKSAlPiUgDQogIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+IDVdKSksIA0KICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAiUFBBVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiXSkpLA0KICAgICAgICAgICAgIlBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpLCANCiAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAiV1RQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSkpICU+JSAgDQogIHNlbGVjdChTaGlwQ2FuY2VsTW9udGgsIA0KICAgICAgICAgUmVwb3J0aW5nQnJhbmQsIA0KICAgICAgICAgU09UVW5pdHMsIA0KICAgICAgICAgU09UT25UaW1lVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQVVuaXRzLA0KICAgICAgICAgUFBBU09UTGF0ZVVuaXRzLA0KICAgICAgICAgUFBBU09UNWRheXNMYXRlVW5pdHMsDQogICAgICAgICBXVFBQQVNPVExhdGVVbml0cykNCiMgVmlldyhNb250aGx5X0JyYW5kX1NPVCkNCg0KIyBDcmVhdGUgTW9udGhseSBTT1QgQ2F0ZWdvcnkgVGFibGUgLS0tLQ0KTW9udGhseV9DYXRlZ29yeV9TT1QgPC0gU09UX01hc3RlciAlPiUNCiAgZmlsdGVyKFNPVF9NYXN0ZXIkU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoU2hpcENhbmNlbE1vbnRoLCBDYXRlZ29yeSkgJT4lIA0KICBzdW1tYXJpc2UoIlNPVFVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIlNPVE9uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVFNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIl0pKSwNCiAgICAgICAgICAgICJQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSwgDQogICAgICAgICAgICAiUFBBU09UNWRheXNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURT41XSkpLA0KICAgICAgICAgICAgIldUUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpKSAlPiUgIA0KICBzZWxlY3QoU2hpcENhbmNlbE1vbnRoLCANCiAgICAgICAgIENhdGVnb3J5LCANCiAgICAgICAgIFNPVFVuaXRzLCANCiAgICAgICAgIFNPVE9uVGltZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICBTT1RMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVFNPVExhdGVVbml0cywgDQogICAgICAgICBQUEFVbml0cywNCiAgICAgICAgIFBQQVNPVExhdGVVbml0cywNCiAgICAgICAgIFBQQVNPVDVkYXlzTGF0ZVVuaXRzLA0KICAgICAgICAgV1RQUEFTT1RMYXRlVW5pdHMpDQojIFZpZXcoTW9udGhseV9DYXRlZ29yeV9TT1QpIA0KDQojIENyZWF0ZSBNb250aGx5IEdhcCBJbmMgU09UIFRhYmxlIC0tLS0NCk1vbnRobHlfR2FwSW5jX1NPVCA8LSBTT1RfTWFzdGVyICU+JQ0KICBmaWx0ZXIoU09UX01hc3RlciRTaGlwQ2FuY2VsV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShTaGlwQ2FuY2VsTW9udGgpICU+JSANCiAgc3VtbWFyaXNlKCJTT1RVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJTT1RPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAiV1RTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSwNCiAgICAgICAgICAgICJQUEFVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciJdKSksDQogICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgIlBQQVNPVDVkYXlzTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEU+NV0pKSwNCiAgICAgICAgICAgICJXVFBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSkgJT4lICANCiAgc2VsZWN0KFNoaXBDYW5jZWxNb250aCwgDQogICAgICAgICBTT1RVbml0cywgDQogICAgICAgICBTT1RPblRpbWVVbml0cywgDQogICAgICAgICBTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RTT1RMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBVW5pdHMsDQogICAgICAgICBQUEFTT1RMYXRlVW5pdHMsDQogICAgICAgICBQUEFTT1Q1ZGF5c0xhdGVVbml0cywNCiAgICAgICAgIFdUUFBBU09UTGF0ZVVuaXRzKQ0KIyBWaWV3KE1vbnRobHlfR2FwSW5jX1NPVCkgDQoNCiMgQ3JlYXRlIE1vbnRobHkgT1RTIEJyYW5kIGFuZCBDYXRlZ29yeSBUYWJsZSAtLS0tDQpNb250aGx5X0JyYW5kX0NhdGVnb3J5X09UUyA8LSBPVFNfTWFzdGVyICU+JQ0KICBmaWx0ZXIoT1RTX01hc3RlciRXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KE1vbnRoX051bWJlciwgUmVwb3J0aW5nQnJhbmQsIENhdGVnb3J5KSAlPiUgDQogIHN1bW1hcmlzZSgiT1RTVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiT1RTT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJPVFNMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+IDVdKSksIA0KICAgICAgICAgICAgIldUT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEYXlzX0xhdGVbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+PTFdKSksDQogICAgICAgICAgICAiUFBBT1RTTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSkpICU+JSAgDQogIHNlbGVjdChNb250aF9OdW1iZXIsIA0KICAgICAgICAgUmVwb3J0aW5nQnJhbmQsIA0KICAgICAgICAgQ2F0ZWdvcnksIA0KICAgICAgICAgT1RTVW5pdHMsIA0KICAgICAgICAgT1RTT25UaW1lVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUT1RTTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQU9UU0xhdGVVbml0cykNCiAjIFZpZXcoTW9udGhseV9CcmFuZF9DYXRlZ29yeV9PVFMpDQoNCiMgQ3JlYXRlIE1vbnRobHkgT1RTIEJyYW5kIFRhYmxlIC0tLS0NCk1vbnRobHlfQnJhbmRfT1RTIDwtIE9UU19NYXN0ZXIgJT4lDQogIGZpbHRlcihPVFNfTWFzdGVyJFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoTW9udGhfTnVtYmVyLCBSZXBvcnRpbmdCcmFuZCkgJT4lIA0KICBzdW1tYXJpc2UoIk9UU1VuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIk9UU09uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVE9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qRGF5c19MYXRlW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQU9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpKSAlPiUgIA0KICBzZWxlY3QoTW9udGhfTnVtYmVyLCANCiAgICAgICAgIFJlcG9ydGluZ0JyYW5kLCANCiAgICAgICAgIE9UU1VuaXRzLCANCiAgICAgICAgIE9UU09uVGltZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGVVbml0cywgDQogICAgICAgICBPVFNMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVE9UU0xhdGVVbml0cywgDQogICAgICAgICBQUEFPVFNMYXRlVW5pdHMpDQojIFZpZXcoTW9udGhseV9CcmFuZF9PVFMpDQoNCiMgQ3JlYXRlIE1vbnRobHkgT1RTIENhdGVnb3J5IFRhYmxlIC0tLS0NCk1vbnRobHlfQ2F0ZWdvcnlfT1RTIDwtIE9UU19NYXN0ZXIgJT4lDQogIGZpbHRlcihPVFNfTWFzdGVyJFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoTW9udGhfTnVtYmVyLCBDYXRlZ29yeSkgJT4lIA0KICBzdW1tYXJpc2UoIk9UU1VuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIk9UU09uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVE9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qRGF5c19MYXRlW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQU9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpKSAlPiUgIA0KICBzZWxlY3QoTW9udGhfTnVtYmVyLCANCiAgICAgICAgIENhdGVnb3J5LCANCiAgICAgICAgIE9UU1VuaXRzLCANCiAgICAgICAgIE9UU09uVGltZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGVVbml0cywgDQogICAgICAgICBPVFNMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVE9UU0xhdGVVbml0cywgDQogICAgICAgICBQUEFPVFNMYXRlVW5pdHMpDQojIFZpZXcoTW9udGhseV9DYXRlZ29yeV9PVFMpDQoNCiMgQ3JlYXRlIE1vbnRobHkgR2FwIEluYyBPVFMgVGFibGUgLS0tLQ0KTW9udGhseV9HYXBJbmNfT1RTIDwtIE9UU19NYXN0ZXIgJT4lDQogIGZpbHRlcihPVFNfTWFzdGVyJFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoTW9udGhfTnVtYmVyKSAlPiUgDQogIHN1bW1hcmlzZSgiT1RTVW5pdHMiID0gc3VtKFVuaXRzKSwNCiAgICAgICAgICAgICJPVFNPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID4gNV0pKSwgDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJQUEFPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lICANCiAgc2VsZWN0KE1vbnRoX051bWJlciwgDQogICAgICAgICBPVFNVbml0cywgDQogICAgICAgICBPVFNPblRpbWVVbml0cywgDQogICAgICAgICBPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBT1RTTGF0ZVVuaXRzKQ0KICMgVmlldyhNb250aGx5X0dhcEluY19PVFMpDQoNCiMgQ3JlYXRlIE1vbnRobHkgLSBQcmVmZXJyZWQgVmVuZG9yIC0gTmV3IC0tLS0NCk1vbnRobHlfUHJlZmVycmVkX1ZlbmRvcl9uZXcgPC0gaW5uZXJfam9pbihTT1RfTWFzdGVyLCBQcmVmZXJyZWRfVmVuZG9yX25ldywgYnkgPSBjKCJDYXRlZ29yeSI9ICJOZXcgQ2F0ZWdvcnkiLCAiUGFyZW50X1ZlbmRvciI9IlZlbmRvciBOYW1lIikpICU+JSANCiAgZmlsdGVyKFNoaXBDYW5jZWxXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KENhdGVnb3J5LCBQYXJlbnRfVmVuZG9yLCBTaGlwQ2FuY2VsTW9udGgpICU+JSANCiAgc3VtbWFyaXNlKCJTT1RVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJTT1RPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAiV1RTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSwNCiAgICAgICAgICAgICJQUEFVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciJdKSksDQogICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgIlBQQVNPVDVkYXlzTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEU+NV0pKSwNCiAgICAgICAgICAgICJXVFBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSkgJT4lICANCiAgc2VsZWN0KENhdGVnb3J5LA0KICAgICAgICAgUGFyZW50X1ZlbmRvciwNCiAgICAgICAgIFNoaXBDYW5jZWxNb250aCwNCiAgICAgICAgIFNPVFVuaXRzLCANCiAgICAgICAgIFNPVE9uVGltZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICBTT1RMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVFNPVExhdGVVbml0cywgDQogICAgICAgICBQUEFVbml0cywNCiAgICAgICAgIFBQQVNPVExhdGVVbml0cywNCiAgICAgICAgIFBQQVNPVDVkYXlzTGF0ZVVuaXRzLA0KICAgICAgICAgV1RQUEFTT1RMYXRlVW5pdHMpICU+JSANCiAgYXJyYW5nZShTaGlwQ2FuY2VsTW9udGgsIENhdGVnb3J5KQ0KIyBDcmVhdGUgTW9udGhseSBQcmVmZXJyZWQgVmVuZG9yIC0gTmV3IE9UUyAtLS0tDQpNb250aGx5X1ByZWZlcnJlZF9WZW5kb3JfTmV3X09UUyA8LSBpbm5lcl9qb2luKE9UU19NYXN0ZXIsIFByZWZlcnJlZF9WZW5kb3JfbmV3LCBieSA9IGMoIkNhdGVnb3J5Ij0gIk5ldyBDYXRlZ29yeSIsICJQYXJlbnRfVmVuZG9yIj0iVmVuZG9yIE5hbWUiKSkgJT4lIA0KICBmaWx0ZXIoV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShDYXRlZ29yeSwgUGFyZW50X1ZlbmRvciwgIE1vbnRoX051bWJlciApICU+JSANCiAgc3VtbWFyaXNlKCJPVFNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICJPVFNPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID4gNV0pKSwgDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJQUEFPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lICANCiAgc2VsZWN0KENhdGVnb3J5LCANCiAgICAgICAgIFBhcmVudF9WZW5kb3IsDQogICAgICAgICBNb250aF9OdW1iZXIsDQogICAgICAgICBPVFNVbml0cywgDQogICAgICAgICBPVFNPblRpbWVVbml0cywgDQogICAgICAgICBPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBT1RTTGF0ZVVuaXRzKSAlPiUgDQogIGFycmFuZ2UoTW9udGhfTnVtYmVyLCBDYXRlZ29yeSkNCiMgVmlldyhNb250aGx5X1ByZWZlcnJlZF9WZW5kb3JfTmV3X09UUykNCg0KDQojIENyZWF0ZSBNb250aGx5IEJyYW5kIGFuZCBDYXRlZ29yeSBDb21iaW5lIFRhYmxlIC0tLS0NCk1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfQ29tYmluZSA8LSBsZWZ0X2pvaW4oTW9udGhseV9CcmFuZF9DYXRlZ29yeV9TT1QsIE1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfT1RTLCBieT0gYygiU2hpcENhbmNlbE1vbnRoIj0iTW9udGhfTnVtYmVyIiwgIlJlcG9ydGluZ0JyYW5kIj0iUmVwb3J0aW5nQnJhbmQiLCAiQ2F0ZWdvcnkiPSJDYXRlZ29yeSIpKQ0KTW9udGhseV9CcmFuZF9DYXRlZ29yeV9Db21iaW5lIDwtIE1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfQ29tYmluZVtjKDE6OCwgMTM6MTcsOToxMCwxOCwxMToxMildDQoNCiMgQ3JlYXRlIE1vbnRobHkgU09UIEJyYW5kIENvbWJpbmUgVGFibGUgLS0tLQ0KTW9udGhseV9CcmFuZF9Db21iaW5lIDwtIGxlZnRfam9pbihNb250aGx5X0JyYW5kX1NPVCwgTW9udGhseV9CcmFuZF9PVFMsIGJ5PSBjKCJTaGlwQ2FuY2VsTW9udGgiPSJNb250aF9OdW1iZXIiLCAiUmVwb3J0aW5nQnJhbmQiPSJSZXBvcnRpbmdCcmFuZCIpKQ0KTW9udGhseV9CcmFuZF9Db21iaW5lIDwtIE1vbnRobHlfQnJhbmRfQ29tYmluZVtjKDE6NywgMTI6MTYsIDg6OSwgMTcsIDEwOjExKV0NCiMgVmlldyhNb250aGx5X0JyYW5kX0NvbWJpbmUpDQoNCiMgQ3JlYXRlIE1vbnRobHkgU09UIENhdGVnb3J5IENvbWJpbmUgVGFibGUgLS0tLQ0KTW9udGhseV9DYXRlZ29yeV9Db21iaW5lIDwtIGxlZnRfam9pbihNb250aGx5X0NhdGVnb3J5X1NPVCwgTW9udGhseV9DYXRlZ29yeV9PVFMsIGJ5PSBjKCJTaGlwQ2FuY2VsTW9udGgiPSJNb250aF9OdW1iZXIiLCAiQ2F0ZWdvcnkiPSJDYXRlZ29yeSIpKQ0KTW9udGhseV9DYXRlZ29yeV9Db21iaW5lIDwtIE1vbnRobHlfQ2F0ZWdvcnlfQ29tYmluZVtjKDE6NywgMTI6MTYsIDg6OSwgMTcsIDEwOjExKV0NCiMgVmlldyhNb250aGx5X0NhdGVnb3J5X0NvbWJpbmUpDQoNCiMgQ3JlYXRlIE1vbnRobHkgU09UIEdhcCBJbmMgQ29tYmluZSBUYWJsZSAtLS0tDQpNb250aGx5X0dhcEluY19Db21iaW5lIDwtIGxlZnRfam9pbihNb250aGx5X0dhcEluY19TT1QsIE1vbnRobHlfR2FwSW5jX09UUywgYnk9IGMoIlNoaXBDYW5jZWxNb250aCI9Ik1vbnRoX051bWJlciIpKQ0KTW9udGhseV9HYXBJbmNfQ29tYmluZSA8LSBNb250aGx5X0dhcEluY19Db21iaW5lW2MoMTo2LCAxMToxNSw3OjgsMTYsOToxMCldDQojIFZpZXcoTW9udGhseV9HYXBJbmNfQ29tYmluZSkNCiMgQ3JlYXRlIFByZWZlcnJlZCBWZW5kb3IgQ29tYmluZSBUYWJsZSAtLS0tDQpQcmVmZXJyZWRfVmVuZG9yX05ld19Db21iaW5lIDwtIGxlZnRfam9pbihNb250aGx5X1ByZWZlcnJlZF9WZW5kb3JfbmV3LCBNb250aGx5X1ByZWZlcnJlZF9WZW5kb3JfTmV3X09UUywgYnkgPSBjKCJDYXRlZ29yeSI9IkNhdGVnb3J5IiwgIlBhcmVudF9WZW5kb3IiPSJQYXJlbnRfVmVuZG9yIiwgIlNoaXBDYW5jZWxNb250aCIgPSAiTW9udGhfTnVtYmVyIikpDQpQcmVmZXJyZWRfVmVuZG9yX05ld19Db21iaW5lIDwtUHJlZmVycmVkX1ZlbmRvcl9OZXdfQ29tYmluZVtjKDE6OCwgMTM6MTcsIDk6MTAsIDE4LCAxMToxMildDQoNCiMgQ3JlYXRlIE1vbnRobHkgLSBieURDDQpNb250aGx5X2J5X0RDIDwtIE9UU19NYXN0ZXIgJT4lIA0KICBmaWx0ZXIoT1RTX01hc3RlciRXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KEZpc2NhbF9Nb250aCwgTW9udGhfTnVtYmVyLCBEQ0NhbXB1cywgRENfTkFNRSwgRGVzdEN0cnlDRCkgJT4lIA0KICBzdW1tYXJpc2UoIlRvdGFsIFVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIk9uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiT1RTJSIgPSBzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkvc3VtKFVuaXRzKSwNCiAgICAgICAgICAgICJPVFNMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERheXNfTGF0ZSA+IDVdKSksDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lIA0KICBzZWxlY3QoRmlzY2FsX01vbnRoLCANCiAgICAgICAgIE1vbnRoX051bWJlciwgDQogICAgICAgICBgT25UaW1lVW5pdHNgLCANCiAgICAgICAgIGBUb3RhbCBVbml0c2AsIA0KICAgICAgICAgRENDYW1wdXMsIA0KICAgICAgICAgRENfTkFNRSwgDQogICAgICAgICBEZXN0Q3RyeUNELCANCiAgICAgICAgIGBPVFMlYCwgDQogICAgICAgICBgT1RTTGF0ZTVkYXlzVW5pdHNgLA0KICAgICAgICAgYFdUT1RTTGF0ZVVuaXRzYCwgDQogICAgICAgICBgTGF0ZVVuaXRzYCkNCiMgQ3JlYXRlIFRvcCAyMCBDb3VudHJpZXMgU09UIC0tLS0NCk1vbnRobHlfVG9wXzIwX1NPVCA8LSBpbm5lcl9qb2luKFNPVF9NYXN0ZXIsIFRvcF8yMF9Db3VudHJpZXMsIGJ5ID0gYygiQ291bnRyeU9mT3JpZ2luIj0gIkNvdW50cnlPZk9yaWdpbiIpKQ0KTW9udGhseV9Ub3BfMjBfU09UIDwtIE1vbnRobHlfVG9wXzIwX1NPVCAlPiUNCiAgZmlsdGVyKFNoaXBDYW5jZWxXZWVrIDw9IEVPVykgJT4lDQogIGdyb3VwX2J5KFNoaXBDYW5jZWxNb250aCkgJT4lIA0KICBzdW1tYXJpc2UoIlNPVFVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpLA0KICAgICAgICAgICAgIlNPVE9uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiU09UTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVFNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIl0pKSwNCiAgICAgICAgICAgICJQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSwgDQogICAgICAgICAgICAiUFBBU09UNWRheXNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURT41XSkpLA0KICAgICAgICAgICAgIldUUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpKSAlPiUgIA0KICBzZWxlY3QoU2hpcENhbmNlbE1vbnRoLCANCiAgICAgICAgIFNPVFVuaXRzLCANCiAgICAgICAgIFNPVE9uVGltZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICBTT1RMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVFNPVExhdGVVbml0cywgDQogICAgICAgICBQUEFVbml0cywNCiAgICAgICAgIFBQQVNPVExhdGVVbml0cywNCiAgICAgICAgIFBQQVNPVDVkYXlzTGF0ZVVuaXRzLA0KICAgICAgICAgV1RQUEFTT1RMYXRlVW5pdHMpDQojIFZpZXcoTW9udGhseV9Ub3BfMjBfU09UKSANCg0KIyBDcmVhdGUgTW9udGhseSBUb3AgMjAgT1RTIFRhYmxlIC0tLS0NCk1vbnRobHlfVE9QXzIwX09UUyA8LSBpbm5lcl9qb2luKE9UU19NYXN0ZXIsIFRvcF8yMF9Db3VudHJpZXMsIGJ5ID0gYygiT1JJR0lOX0NPVU5UUllfQ09ERSI9IkNvdW50cnlPZk9yaWdpbiIpKQ0KTW9udGhseV9UT1BfMjBfT1RTIDwtIE1vbnRobHlfVE9QXzIwX09UUyAlPiUNCiAgZmlsdGVyKFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoTW9udGhfTnVtYmVyKSAlPiUgDQogIHN1bW1hcmlzZSgiT1RTVW5pdHMiID0gc3VtKFVuaXRzKSwNCiAgICAgICAgICAgICJPVFNPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGVVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgIk9UU0xhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID4gNV0pKSwgDQogICAgICAgICAgICAiV1RPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRheXNfTGF0ZVtMYXRlbmVzcz09IkxhdGUiICYgRGF5c19MYXRlID49MV0pKSwNCiAgICAgICAgICAgICJQUEFPVFNMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSkgJT4lICANCiAgc2VsZWN0KE1vbnRoX051bWJlciwgDQogICAgICAgICBPVFNVbml0cywgDQogICAgICAgICBPVFNPblRpbWVVbml0cywgDQogICAgICAgICBPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgT1RTTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgV1RPVFNMYXRlVW5pdHMsIA0KICAgICAgICAgUFBBT1RTTGF0ZVVuaXRzKQ0KIyAgVmlldyhNb250aGx5X1RPUF8yMF9PVFMpDQojIENyZWF0ZSBNb250aGx5IFRvcCAyMCBDb21iaW5lIHRhYmxlIC0tLS0NCk1vbnRobHlfVG9wXzIwX0NvbWJpbmUgPC0gaW5uZXJfam9pbihNb250aGx5X1RvcF8yMF9TT1QsIE1vbnRobHlfVE9QXzIwX09UUywgYnk9IGMoIlNoaXBDYW5jZWxNb250aCI9Ik1vbnRoX051bWJlciIpKQ0KTW9udGhseV9Ub3BfMjBfQ29tYmluZSA8LSBNb250aGx5X1RvcF8yMF9Db21iaW5lW2MoMTo2LCAxMToxNSw3OjgsMTYsOToxMCldDQogIA0KIyBDcmVhdGUgTW9udGhseSBUb3AgNTAgVmVuZG9ycyBTT1QgVGFibGUgLS0tLQ0KTW9udGhseV9Ub3BfNTBfVmVuZG9yc19TT1QgPC0gaW5uZXJfam9pbihTT1RfTWFzdGVyLCBUb3BfNTBfVmVuZG9ycywgYnkgPSBjKCJQYXJlbnRfVmVuZG9yIj0gIlBhcmVudF9WZW5kb3IiKSkNCk1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfU09UIDwtIE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfU09UICU+JQ0KICBmaWx0ZXIoU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgZ3JvdXBfYnkoU2hpcENhbmNlbE1vbnRoKSAlPiUgDQogIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICJTT1RMYXRlNWRheXNVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+IDVdKSksIA0KICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAiUFBBVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiXSkpLA0KICAgICAgICAgICAgIlBQQVNPVExhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpLCANCiAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAiV1RQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSkpICU+JSAgDQogIHNlbGVjdChTaGlwQ2FuY2VsTW9udGgsIA0KICAgICAgICAgU09UVW5pdHMsIA0KICAgICAgICAgU09UT25UaW1lVW5pdHMsIA0KICAgICAgICAgU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFNPVExhdGU1ZGF5c1VuaXRzLCANCiAgICAgICAgIFdUU09UTGF0ZVVuaXRzLCANCiAgICAgICAgIFBQQVVuaXRzLA0KICAgICAgICAgUFBBU09UTGF0ZVVuaXRzLA0KICAgICAgICAgUFBBU09UNWRheXNMYXRlVW5pdHMsDQogICAgICAgICBXVFBQQVNPVExhdGVVbml0cykNCiAjIFZpZXcoTW9udGhseV9Ub3BfNTBfVmVuZG9yc19TT1QpIA0KIyBDcmVhdGUgTW9udGhseSBUb3AgNTAgVmVuZG9ycyBPVFMgVGFibGUgLS0tLQ0KTW9udGhseV9Ub3BfNTBfVmVuZG9yc19PVFMgPC0gaW5uZXJfam9pbihPVFNfTWFzdGVyLCBUb3BfNTBfVmVuZG9ycywgYnkgPSBjKCJQYXJlbnRfVmVuZG9yIj0gIlBhcmVudF9WZW5kb3IiKSkNCk1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfT1RTIDwtIE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfT1RTICU+JQ0KICBmaWx0ZXIoV2VlayA8PSBFT1cpICU+JQ0KICBncm91cF9ieShNb250aF9OdW1iZXIpICU+JSANCiAgc3VtbWFyaXNlKCJPVFNVbml0cyIgPSBzdW0oVW5pdHMpLA0KICAgICAgICAgICAgIk9UU09uVGltZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAiT1RTTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPiA1XSkpLCANCiAgICAgICAgICAgICJXVE9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0qRGF5c19MYXRlW0xhdGVuZXNzPT0iTGF0ZSIgJiBEYXlzX0xhdGUgPj0xXSkpLA0KICAgICAgICAgICAgIlBQQU9UU0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiXSkpKSAlPiUgIA0KICBzZWxlY3QoTW9udGhfTnVtYmVyLCANCiAgICAgICAgIE9UU1VuaXRzLCANCiAgICAgICAgIE9UU09uVGltZVVuaXRzLCANCiAgICAgICAgIE9UU0xhdGVVbml0cywgDQogICAgICAgICBPVFNMYXRlNWRheXNVbml0cywgDQogICAgICAgICBXVE9UU0xhdGVVbml0cywgDQogICAgICAgICBQUEFPVFNMYXRlVW5pdHMpDQogIyBWaWV3KE1vbnRobHlfR2FwSW5jX09UUykNCg0KDQojIENyZWF0ZSBNb250aGx5IFNPVCBUb3AgNTAgVmVuZG9ycyBDb21iaW5lIFRhYmxlIC0tLS0NCk1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfQ29tYmluZSA8LSBsZWZ0X2pvaW4oTW9udGhseV9Ub3BfNTBfVmVuZG9yc19TT1QsIE1vbnRobHlfVG9wXzUwX1ZlbmRvcnNfT1RTLCBieT0gYygiU2hpcENhbmNlbE1vbnRoIj0iTW9udGhfTnVtYmVyIikpDQpNb250aGx5X1RvcF81MF9WZW5kb3JzX0NvbWJpbmUgPC0gTW9udGhseV9Ub3BfNTBfVmVuZG9yc19Db21iaW5lW2MoMTo2LCAxMToxNSw3OjgsMTYsOToxMCldDQojIFZpZXcoTW9udGhseV9Ub3BfNTBfX1ZlbmRvcnNfQ29tYmluZSkNCiMgQ3JlYXRlIE9UU3ZzU09UIHRhYmxlIC0tLS0NCiBPVFNfdnMgPC0gT1RTX01hc3RlciAlPiUgDQogICBzZWxlY3QoTlVNQkVSX1NFUSwgTW9udGhfTnVtYmVyLCBMYXRlbmVzcywgVW5pdHMpICU+JQ0KICAgZmlsdGVyKExhdGVuZXNzIT0gIlVuZGV0ZXJtaW5lZCIpICU+JSANCiAgIHJlbmFtZSgiU3RvY2tlZE9uVGltZSIgPSBMYXRlbmVzcykgJT4lDQogICBncm91cF9ieShNb250aF9OdW1iZXIsIFN0b2NrZWRPblRpbWUpICU+JSANCiAgIGRyb3BsZXZlbHMoKQ0KIA0KIFNPVF92cyA8LSBTT1RfTWFzdGVyICU+JSANCiAgIHNlbGVjdChOVU1CRVJfU0VRLCBTaGlwQ2FuY2VsTW9udGgsIExhdGVuZXNzKSAlPiUNCiAgIGZpbHRlcihMYXRlbmVzcyE9IlVubWVhc3VyZWQiKSAlPiUgDQogICByZW5hbWUoIlNoaXBwZWRPblRpbWUiID0gTGF0ZW5lc3MpICU+JQ0KICAgZ3JvdXBfYnkoU2hpcENhbmNlbE1vbnRoLCBTaGlwcGVkT25UaW1lKSAlPiUgDQogICBkcm9wbGV2ZWxzKCkNCiANCiBPVFN2c1NPVCA8LSBpbm5lcl9qb2luKE9UU192cywgU09UX3ZzLCBieSA9IGMoIk5VTUJFUl9TRVEiPSAiTlVNQkVSX1NFUSIpKSAlPiUNCiAgIGdyb3VwX2J5KE1vbnRoX051bWJlciwgU3RvY2tlZE9uVGltZSwgU2hpcHBlZE9uVGltZSkgJT4lIA0KICAgc3VtbWFyaXNlKCJTdW1PZlVuaXRzIiA9IGZsb29yKHN1bShVbml0cykpKQ0KIA0KIyBDcmVhdGUgTW9udGhseSBCcmFuZCBUb3AgMTAgRGVsYXkgQ29tYmluZSAtLS0tDQpCcmFuZF9Ub3BfVGVuX0RlbGF5IDwtICBTT1RfTWFzdGVyICU+JSANCiAgIGZpbHRlcihTaGlwQ2FuY2VsV2VlayA8PSBFT1cpICU+JQ0KICAgZ3JvdXBfYnkoUmVwb3J0aW5nQnJhbmQsIFNoaXBDYW5jZWxNb250aCwgUGFyZW50X1ZlbmRvcikgJT4lIA0KICAgc3VtbWFyaXNlKCJTT1RVbml0cyIgPSBmbG9vcihzdW0oVW5pdHMpKSwNCiAgICAgICAgICAgICAiQWRqdXN0ZWRTT1RVbml0cyI9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09Ik9uVGltZSJdKSArIHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSkpLA0KICAgICAgICAgICAgICJTT1RPblRpbWVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkpLA0KICAgICAgICAgICAgICJTT1RMYXRlVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICAiU09UTGF0ZTVkYXlzVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPiA1XSkpLCANCiAgICAgICAgICAgICAiV1RTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID49MV0pKSwNCiAgICAgICAgICAgICAiUFBBVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiXSkpLA0KICAgICAgICAgICAgICJQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0pKSwgDQogICAgICAgICAgICAgIlBQQVNPVDVkYXlzTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEU+NV0pKSwNCiAgICAgICAgICAgICAiV1RQUEFTT1RMYXRlVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIl0qREFZU19MQVRFW1NIUF9NT0RFX0NBVEdfTk0gPT0gIlByZXBhaWRBaXIiICYgTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSkpICU+JSAgDQogICBzZWxlY3QoDQogICAgICAgICAgUmVwb3J0aW5nQnJhbmQsDQogICAgICAgICAgU2hpcENhbmNlbE1vbnRoLA0KICAgICAgICAgIFBhcmVudF9WZW5kb3IsDQogICAgICAgICAgU09UVW5pdHMsDQogICAgICAgICAgQWRqdXN0ZWRTT1RVbml0cywNCiAgICAgICAgICBTT1RPblRpbWVVbml0cywgDQogICAgICAgICAgU09UTGF0ZVVuaXRzLCANCiAgICAgICAgICBTT1RMYXRlNWRheXNVbml0cywgDQogICAgICAgICAgV1RTT1RMYXRlVW5pdHMpICU+JSANCiAgIHRvcF9uKDEwLCBTT1RMYXRlVW5pdHMpICU+JSANCiAgIGFycmFuZ2UoUmVwb3J0aW5nQnJhbmQsU2hpcENhbmNlbE1vbnRoLCBkZXNjKFNPVExhdGVVbml0cykpDQogICANCiMgQ3JlYXRlIE1vbnRobHkgQ2F0ZWdvcnkgVG9wIDEwIERlbGF5IENvbWJpbmUgLS0tLQ0KQ2F0ZWdvcnlfVG9wX1Rlbl9EZWxheSA8LSAgU09UX01hc3RlciAlPiUgDQogICBmaWx0ZXIoU2hpcENhbmNlbFdlZWsgPD0gRU9XKSAlPiUNCiAgIGdyb3VwX2J5KENhdGVnb3J5LCBTaGlwQ2FuY2VsTW9udGgsIFBhcmVudF9WZW5kb3IpICU+JSANCiAgIHN1bW1hcmlzZSgiU09UVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzKSksDQogICAgICAgICAgICAgIkFkanVzdGVkU09UVW5pdHMiPSBmbG9vcihzdW0oVW5pdHNbTGF0ZW5lc3M9PSJPblRpbWUiXSkgKyBzdW0oVW5pdHNbTGF0ZW5lc3M9PSJMYXRlIl0pKSwNCiAgICAgICAgICAgICAiU09UT25UaW1lVW5pdHMiID0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iT25UaW1lIl0pKSwNCiAgICAgICAgICAgICAiU09UTGF0ZVVuaXRzIj0gZmxvb3Ioc3VtKFVuaXRzW0xhdGVuZXNzPT0iTGF0ZSJdKSksDQogICAgICAgICAgICAgIlNPVExhdGU1ZGF5c1VuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFID4gNV0pKSwgDQogICAgICAgICAgICAgIldUU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tMYXRlbmVzcz09IkxhdGUiXSpEQVlTX0xBVEVbTGF0ZW5lc3M9PSJMYXRlIiAmIERBWVNfTEFURSA+PTFdKSksDQogICAgICAgICAgICAgIlBQQVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIl0pKSwNCiAgICAgICAgICAgICAiUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKSksIA0KICAgICAgICAgICAgICJQUEFTT1Q1ZGF5c0xhdGVVbml0cyIgPSBmbG9vcihzdW0oVW5pdHNbU0hQX01PREVfQ0FUR19OTSA9PSAiUHJlcGFpZEFpciIgJiBMYXRlbmVzcz09IkxhdGUiICYgREFZU19MQVRFPjVdKSksDQogICAgICAgICAgICAgIldUUFBBU09UTGF0ZVVuaXRzIiA9IGZsb29yKHN1bShVbml0c1tTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSJdKkRBWVNfTEFURVtTSFBfTU9ERV9DQVRHX05NID09ICJQcmVwYWlkQWlyIiAmIExhdGVuZXNzPT0iTGF0ZSIgJiBEQVlTX0xBVEUgPj0xXSkpKSAlPiUgIA0KICAgc2VsZWN0KA0KICAgICAgICAgIENhdGVnb3J5LA0KICAgICAgICAgIFNoaXBDYW5jZWxNb250aCwNCiAgICAgICAgICBQYXJlbnRfVmVuZG9yLA0KICAgICAgICAgIFNPVFVuaXRzLA0KICAgICAgICAgIEFkanVzdGVkU09UVW5pdHMsDQogICAgICAgICAgU09UT25UaW1lVW5pdHMsIA0KICAgICAgICAgIFNPVExhdGVVbml0cywgDQogICAgICAgICAgU09UTGF0ZTVkYXlzVW5pdHMsIA0KICAgICAgICAgIFdUU09UTGF0ZVVuaXRzKSAlPiUgDQogICB0b3BfbigxMCwgU09UTGF0ZVVuaXRzKSAlPiUgDQogICBhcnJhbmdlKENhdGVnb3J5LCBTaGlwQ2FuY2VsTW9udGgsIGRlc2MoU09UTGF0ZVVuaXRzKSkNCiAgIA0KIyBXcml0ZSB0YWJsZXMgLS0tLQ0Kd3JpdGVfY3N2KE1vbnRobHlfQnJhbmRfQ2F0ZWdvcnlfQ29tYmluZSwgDQogICAgICAgICAgcGF0aCA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgDQogICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCdNb250aGx5X0JyYW5kX0NhdGVnb3J5X0NvbWJpbmVfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihNb250aGx5X0JyYW5kX0NvbWJpbmUsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnTW9udGhseV9CcmFuZF9Db21iaW5lX1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQp3cml0ZV9jc3YoTW9udGhseV9DYXRlZ29yeV9Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfQ2F0ZWdvcnlfQ29tYmluZV9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KE1vbnRobHlfR2FwSW5jX0NvbWJpbmUsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnTW9udGhseV9HYXBJbmNfQ29tYmluZV9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KFByZWZlcnJlZF9WZW5kb3JfTmV3X0NvbWJpbmUsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnUHJlZmVycmVkX1ZlbmRvcl9OZXdfQ29tYmluZV9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KE1vbnRobHlfYnlfREMsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnTW9udGhseV9ieV9EQ19XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KE1vbnRobHlfVG9wXzIwX0NvbWJpbmUsIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnTW9udGhseV9Ub3BfMjBfQ291bnRyaWVzX1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQp3cml0ZV9jc3YoTW9udGhseV9Ub3BfNTBfVmVuZG9yc19Db21iaW5lLCANCiAgICAgICAgICBwYXRoID0gcGFzdGUoU09UX09UU19kaXJlY3RvcnksICANCiAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUoJ01vbnRobHlfVG9wXzUwX1ZlbmRvcnNfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCndyaXRlX2NzdihPVFN2c1NPVCwgDQogICAgICAgICAgcGF0aCA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgDQogICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCdPVFN2c1NPVF9XRV8nLCBFT1csICcuY3N2JyxzZXAgPSAiIiksIHNlcCA9ICcvJyApKQ0Kd3JpdGVfY3N2KEJyYW5kX1RvcF9UZW5fRGVsYXksIA0KICAgICAgICAgIHBhdGggPSBwYXN0ZShTT1RfT1RTX2RpcmVjdG9yeSwgIA0KICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZSgnQnJhbmRfVG9wXzEwX0RlbGF5X1dFXycsIEVPVywgJy5jc3YnLHNlcCA9ICIiKSwgc2VwID0gJy8nICkpDQp3cml0ZV9jc3YoQ2F0ZWdvcnlfVG9wX1Rlbl9EZWxheSwgDQogICAgICAgICAgcGF0aCA9IHBhc3RlKFNPVF9PVFNfZGlyZWN0b3J5LCAgDQogICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKCdDYXRlZ29yeV9Ub3BfMTBfRGVsYXlfV0VfJywgRU9XLCAnLmNzdicsc2VwID0gIiIpLCBzZXAgPSAnLycgKSkNCg0KDQpgYGANCg0K